﻿using MF_Base;
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MFTool;
using MF_Base.Model;
using AutoUI.Areas.ConfigUI.EasyUICtrl;
using UIBase;
using System.Reflection;
using System.Data;
using DocumentIndex;

namespace AutoUI.Areas.ConfigUI.Controllers
{
    [Export]
    public class ListController : BaseController
    {
        public ActionResult PageView()
        {
            string code = QueryString("UICode");
            var list = UnitOfWork.GetSingle<ListConfig>(a => a.UICode == code);
            list.CheckNotNull("未找到列表");
            DataGrid dg = GetDataGrid(list);
            List<Button> btnList = GetButtonList(list);

            ViewBag.ListHtml = dg.GetCtrlHtm();
            ViewBag.ButtonHtml = string.Join("\n\r", btnList.Select(a => a.GetCtrlHtm()));
            ViewBag.QuickSearchColumTitle = string.Join("或", list.GetQuickSearchColumnTitleList());
            ViewBag.ListId = list.Id;
            ViewBag.FormSearchCtrlHtml = GetFormSearchCtrlHtml(list);
            ViewBag.Title = list.Name;

            ViewBag.Script = dg.GetScript() + "\n\r" + list.Script;
            return View();
        }

        public JsonResult GetList(QueryBulider qb, string UICode)
        {
            string code = UICode;
            var list = UnitOfWork.GetSingle<ListConfig>(a => a.UICode == code);
            list.CheckNotNull("未找到列表");
            string sql = list.SQL;

            //快查过滤
            string quickSearchValue = QueryString("QuickSearchValue");
            if (!string.IsNullOrEmpty(quickSearchValue))
            {
                var quickSearchColumnFieldList = list.GetQuickSearchColumnFieldList();
                string tmpWhereStr = "";
                foreach (var field in quickSearchColumnFieldList)
                {
                    tmpWhereStr += string.Format(" or {0} like '%{1}%'", field, quickSearchValue);
                }

                if (!string.IsNullOrEmpty(tmpWhereStr))
                    sql = string.Format("select * from ({0} where 1=0 {1}) original", sql, tmpWhereStr);
            }

            #region 全文检索过滤
            if (qb.QueryItems != null)
            {
                var queryItemList = qb.QueryItems.Where(a => a.SearchCtrlType == SearchControlType.TextContentBox.ToString());
                List<string> contentWhereStrArr = new List<string>();
                foreach (var queryItem in queryItemList)
                {
                    if (string.IsNullOrEmpty(queryItem.FieldValue)) continue;

                    var resList = SearchIndexManager.GetInstance().SearchAll(queryItem.FieldValue);
                    var resIds = string.Join("','", resList.Select(a => a.Id));
                    contentWhereStrArr.Add("substring({0},1,36) in ('{1}')".ReplaceArg(queryItem.FieldName, resIds));
                }

                if (contentWhereStrArr.Count() > 0)
                {
                    string contentWhereStr = string.Join(" or ", contentWhereStrArr);
                    sql = string.Format("select * from ({0}) contentTmp where {1}", sql, contentWhereStr);
                }
            }
            #endregion

            if (qb.QueryItems != null)
                qb.QueryItems.RemoveAll(a => a.SearchCtrlType == SearchControlType.TextContentBox.ToString());

            var res = SqlHelper.CreateSqlHelper(list.ModuleName).ExcuteDataGrid(sql, qb, list.OrderBy);
            return Json(res);
        }

        public JsonResult Delete(string ids)
        {
            string code = QueryString("UICode");
            code.CheckNotNullOrEmpty("UICode");
            var listConfig = UnitOfWork.GetSingle<ListConfig>(a => a.UICode == code);
            listConfig.CheckNotNull("listConfig");
            ids.CheckNotNullOrEmpty("ids");
            var idArr = ids.JsonToObject<IEnumerable<string>>();

            string entityFullName = listConfig.EntityFullName;
            entityFullName.CheckNotNull("编号为{0}的列表定义未绑定实体类全名EntityFullName,无法执行删除".ReplaceArg(code));
            string projName = listConfig.ModuleName;
            Type entityType = ReflectionHelper.GetTypeBy(projName, entityFullName);

            var delMethod = typeof(EFBase.UnitOfWork).GetMethod("DeleteByKey", BindingFlags.Instance | BindingFlags.Public);
            delMethod.CheckNotNull("UnitOfWork中的DeleteByKey方法未找到或者不可访问");
            delMethod = delMethod.MakeGenericMethod(entityType);
            BeforeDelete(idArr);//
            foreach (var id in idArr)
            {
                delMethod.Invoke(UnitOfWork, new object[] { id });
            }
            return Json(UnitOfWork.Commit());
        }

        public virtual void BeforeDelete(IEnumerable<string> ids)
        {

        }

        public JsonResult ExportExcel()
        {
            string code = QueryString("UICode");
            code.CheckNotNullOrEmpty("UICode");
            var listConfig = UnitOfWork.GetSingle<ListConfig>(a => a.UICode == code);
            listConfig.CheckNotNull("listConfig");
            var colList = listConfig.GetColumnList();//列设置
            #region 数据库数据
            string sql = listConfig.SQL;
            if (!string.IsNullOrEmpty(listConfig.OrderBy))
            {
                if (!listConfig.OrderBy.ToLower().Contains("order") && !listConfig.OrderBy.ToLower().Contains("by"))
                {
                    sql += (" order by " + listConfig.OrderBy);
                }
                else
                {
                    sql += (" " + listConfig.OrderBy);
                }
            }

            var res = UnitOfWork.DynamicListFromSql(listConfig.ModuleName, sql);
            #endregion
            //fieldName替换为标题
            var dt = DictionaryExtend.ConvertDicToTable(res.ToList());
            foreach (DataColumn dataCol in dt.Columns)
            {
                var colItem = colList.FirstOrDefault(a => a.GetValue("field") == dataCol.ColumnName);
                if (colItem != null)
                {
                    dataCol.ColumnName = colItem.GetValue("title");
                }
            }
            NPOIExcelHelper.ExportByWeb(dt, listConfig.Name, listConfig.Name);
            return Json("");
        }

        #region 详细搜索
        private List<Dictionary<string, string>> GetFormSearchCtrlHtml(ListConfig listConfig)
        {
            List<Dictionary<string, string>> resList = new List<Dictionary<string, string>>();
            var colList = listConfig.GetColumnList();
            foreach (var col in colList)
            {
                string searchCtrlType = col.GetValue("SearchCtrlType");
                if (string.IsNullOrEmpty(searchCtrlType))
                    continue;

                string title = "", html = "";
                string dataOptions = col.GetValue("SearchCtrlDetail");

                //日期类型查询要生成两个datebox控件
                if (searchCtrlType == SearchControlType.DateBox.ToString())
                {
                    title = col.GetValue("title");
                    var dOptionDic = dataOptions.JsonToDictionary();
                    dOptionDic.SetValue("style_width", "48%");
                    //起始
                    {
                        EasyUICtrlPrepareData prepareData = new EasyUICtrlPrepareData()
                        {
                            DataOptions = dOptionDic
                        };
                        var searchCtrlFrom = EasyUICtrlFactory.GetCtrl(searchCtrlType, col.GetValue("field"), prepareData);
                        searchCtrlFrom.PrepareSearchCtrl();
                        html += searchCtrlFrom.GetCtrlHtm();
                        html += "~";
                    }

                    //终止
                    {
                        EasyUICtrlPrepareData prepareData = new EasyUICtrlPrepareData()
                        {
                            DataOptions = dOptionDic
                        };
                        var searchCtrlTo = EasyUICtrlFactory.GetCtrl(searchCtrlType, col.GetValue("field"), prepareData);
                        searchCtrlTo.PrepareSearchCtrl();
                        html += searchCtrlTo.GetCtrlHtm();
                    }
                }
                else
                {
                    var dOptionDic = dataOptions.JsonToDictionary();
                    EasyUICtrlPrepareData prepareData = new EasyUICtrlPrepareData()
                    {
                        DataOptions = dOptionDic
                    };

                    var searchCtrl = EasyUICtrlFactory.GetCtrl(searchCtrlType, col.GetValue("field"), prepareData);
                    searchCtrl.PrepareSearchCtrl();
                    title = col.GetValue("title");
                    html = searchCtrl.GetCtrlHtm();
                }

                var dic = new Dictionary<string, string>();
                dic.SetValue("title", title);
                dic.SetValue("relationSymbol", col.GetValue("RelationSymbol"));
                dic.SetValue("ctrl", html);
                dic.SetValue("searchCtrlTypeSymbol", searchCtrlType);

                resList.Add(dic);
            }

            return resList;
        }
        #endregion

        private DataGrid GetDataGrid(ListConfig listConfig)
        {
            var propertyDic = listConfig.PropertySetting.JsonToDictionary();
            var dataOptions = new Dictionary<string, object>();

            EasyUICtrlPrepareData pData = new EasyUICtrlPrepareData()
            {
                DataOptions = dataOptions,
                Attr = propertyDic
            };

            List<Dictionary<string, object>> collist = listConfig.ColumnSetting.JsonToDictionaryList();
            DataGrid dg = new DataGrid("mf_grid", pData, collist);
            dg.Prepare();
            return dg;
        }

        private List<Button> GetButtonList(ListConfig listConfig)
        {
            List<Button> buttonList = new List<Button>();
            var buttonDicList = listConfig.GetButtonList();
            foreach (var buttonDic in buttonDicList)
            {
                var detailDic = buttonDic.GetValue("Detail").JsonToDictionary();
                var attr = new Dictionary<string, object>();

                string title = buttonDic.GetValue("title");
                buttonDic.Remove("title");
                if (!string.IsNullOrEmpty(detailDic.GetValue("onclick")))
                {
                    if (!string.IsNullOrEmpty(detailDic.GetValue("mustSelect")))
                    {
                        string action = string.Format("checkSelection(\"{0}\",\"{1}\")", detailDic.GetValue("mustSelect"), detailDic.GetValue("onclick"));
                        buttonDic.SetValue("onclick", action);
                    }
                    else
                    {
                        buttonDic.SetValue("onclick", detailDic.GetValue("onclick"));
                    }
                }
                else if (!string.IsNullOrEmpty(buttonDic.GetValue("url")))
                {
                    string url = buttonDic.GetValue("url");
                    //高宽
                    string width = detailDic.GetValue("width");
                    string height = detailDic.GetValue("height");

                    if (!string.IsNullOrEmpty(detailDic.GetValue("mustSelect")))
                    {
                        string clickCmd = "\"openWindowWithUrl(\\\"" + url + "\\\",\\\"" + width + "\\\",\\\"" + height + "\\\")\"";
                        string action = string.Format("checkSelection(\"{0}\",{1})", detailDic.GetValue("mustSelect"), clickCmd);
                        buttonDic.SetValue("onclick", action);
                    }
                    else
                    {
                        string clickCmd = "openWindowWithUrl(\"" + url + "\")";
                        buttonDic.SetValue("onclick", clickCmd);
                    }
                    buttonDic.Remove("url");
                }

                var classNames = new List<string>();
                if (buttonDic.GetValue("hidden").ToLower() == "true")
                {
                    classNames.Add("euiCtrlHidden");
                }

                EasyUICtrlPrepareData pData = new EasyUICtrlPrepareData()
                {
                    Attr = buttonDic,
                    ClassNames = classNames
                };
                Button dg = new Button(buttonDic.GetValue("id"), pData, title);
                dg.Prepare();
                buttonList.Add(dg);
            }

            return buttonList;
        }
    }
}